package com.dk.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dk.bean.Result;
import com.dk.em.ResultEnum;

import com.dk.mapper.CooperativeMerchantMapper;
import com.dk.pojo.Appointment;
import com.dk.pojo.CooperativeMerchant;
import com.dk.service.AppointmentService;
import com.dk.service.CooperativeMerchantService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 帅杰
 * @since 2021-08-13
 */
@RestController
@RequestMapping("/appointment")
public class AppointmentController {
    private static final double EARTH_RADIUS = 6371000;//赤道半径(单位m)

    private static final double INTEGR_NUM = 10000;

    @Autowired
    private AppointmentService appointmentService;

    @Autowired
    private CooperativeMerchantService cooperativeMerchantService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping
    public Result toInsert(@RequestBody Appointment appointment){
        List<CooperativeMerchant> rdis = new ArrayList<>();
        Integer integer = appointmentService.toInsert(appointment);
        getRedis(appointment);
            Set<Long> set = redisTemplate.boundZSetOps("商家"+appointment.getUserId()).reverseRangeWithScores(0l, 2l);
            Iterator iterator = set.iterator();
            while (iterator.hasNext()){
                Long next = (Long)iterator.next();
                CooperativeMerchant cooperativeMerchant = cooperativeMerchantService.toSelectById(next);
                rdis.add(cooperativeMerchant);
            }
        return Result.buildResult(ResultEnum.SUCCESS).setData(rdis);
    }

    public void getRedis(Appointment appointment){
        JSONObject data = getData(appointment.getAddress());
        JSONArray geocodes = data.getJSONArray("geocodes");
        JSONObject jsonObject = geocodes.getJSONObject(0);
        String location = jsonObject.getString("location");
        String[] split = location.split(",");
        String s = split[0];
        Double one = new Double(s);
        String x = split[1];
        Double two = new Double(x);
        List<CooperativeMerchant> crelan = cooperativeMerchantService.toSelect();
        for (CooperativeMerchant merchant:crelan) {
            String distance = distance(one, two, new Double(merchant.getAccuracy()), new Double(merchant.getLatitude()));
            Double aDouble = new Double(distance);
            redisTemplate.boundZSetOps("商家"+appointment.getUserId()).add(merchant.getMerchantId(),aDouble);
            redisTemplate.expire(merchant.getMerchantId(),2, TimeUnit.MINUTES);
        }
    }



    /**
     * @param request 请求
     * @return 返回用户真实ip
     */
    public static String getIpAddr(HttpServletRequest request) {
        String Xip = request.getHeader("X-Real-IP");
        String XFor = request.getHeader("X-Forwarded-For");
        if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = XFor.indexOf(",");
            if (index != -1) {
                return XFor.substring(0, index);
            } else {
                return XFor;
            }
        }
        XFor = Xip;
        if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
            return XFor;
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getRemoteAddr();
        }
        return XFor;
    }

    /**
     *
     * @param ipAddr  根据请求计算出的ip参数
     * @return 返回的调用百度api接口生成的参数
     */
    public JSONObject getData(String ipAddr){
        RestTemplate restTemplate = new RestTemplate();
        String path = "https://restapi.amap.com/v3/geocode/geo?address=" + ipAddr +"&key=3550c20620468f80d8f974601492d829";
        return restTemplate.getForObject(path, JSONObject.class);
    }

    /**
     *
     @param lat1 第一个经度
      * @param lng1 第一个纬度
     * @param lat2 第二个经度
     * @param lng2 第二个纬度
     * @return 两个经纬度之间的距离
     */
    public String distance(double lat1, double lng1, double lat2, double lng2) {

        double x1 = Math.cos(lat1) * Math.cos(lng1);

        double y1 = Math.cos(lat1) * Math.sin(lng1);

        double z1 = Math.sin(lat1);

        double x2 = Math.cos(lat2) * Math.cos(lng2);

        double y2 = Math.cos(lat2) * Math.sin(lng2);

        double z2 = Math.sin(lat2);

        double lineDistance =

                Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));

        double s = EARTH_RADIUS * Math.PI * 2 * Math.asin(0.5 * lineDistance) / 180;
        //判断计算两个经纬度的值是否大于1000
        if (Math.round(s * INTEGR_NUM) / INTEGR_NUM > 1000) {
            //大于
            double v = Math.round(s * INTEGR_NUM) / INTEGR_NUM / 1000;
            BigDecimal b = new BigDecimal(v);
            double v1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            return v1 + "";


        } else {
            BigDecimal b = new BigDecimal((Math.round(s * INTEGR_NUM) / INTEGR_NUM));
            double v = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            return v + "";
        }
    }

}

